package br.com.rhinovet.util;


import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.xml.datatype.XMLGregorianCalendar;

public class DataUtil {

	public static final SimpleDateFormat dataFormat = new SimpleDateFormat("dd/MM/yy");

	public static final SimpleDateFormat dataPadraoMySQl = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	public static final SimpleDateFormat dataHoraFormat = new SimpleDateFormat("dd/MM/yy HH:mm:ss");

	public static Integer obterAnoAtual(){
		Calendar dataAtual = Calendar.getInstance();
		Integer anoCorrente = dataAtual.get(Calendar.YEAR);
		return anoCorrente;
	}

	public static boolean validaData(Object objeto) {
		if (objeto == null) {
			return false;
		}
		if (objeto instanceof Date || objeto instanceof java.sql.Date) {
			return true;
		}
		try {
			dataFormat.format(objeto);
		} catch (Exception e) {
			return false;
		}	
		return true;
	}


	public static String convertDataParaString(Object objeto, SimpleDateFormat dataPadraoMySQl) {
		if (objeto != null) {
			try {
				if (objeto instanceof Date) {
					return dataPadraoMySQl.format((Date) objeto);
				} else if (objeto instanceof XMLGregorianCalendar) {
					XMLGregorianCalendar calendar = (XMLGregorianCalendar) objeto;
					Date data = calendar.toGregorianCalendar().getTime();
					return dataPadraoMySQl.format((Date) data);
				}
			} catch (Exception e) {
				return null;
			}
		}
		return null;
	}

	public static String converteDataParaString(Date data, boolean exibeHoras) {
		if(data == null) {
			return "";
		}
		if (exibeHoras) {
			return dataHoraFormat.format(data);
		} else {
			return dataFormat.format(data);
		}
		
	}

	public static Date prepararDataInicioDia(Date dataInicio) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(dataInicio);

		cal.set(Calendar.HOUR, 0);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);

		Date dataInicioDia = cal.getTime();

		return dataInicioDia;
	}

	public static Date prepararDataFimDia(Date dataFinal) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(dataFinal);

		cal.set(Calendar.HOUR, 23);
		cal.set(Calendar.MINUTE, 59);
		cal.set(Calendar.SECOND, 59);
		cal.set(Calendar.MILLISECOND, 999);

		Date dataFimDia = cal.getTime();

		return dataFimDia;
	}


	/**
	 * M�todo para calcular a diferen�a em
	 * Dias / Horas / Minutos / Segundos entre duas datas
	 * 
	 * @param dataInicial
	 * @param dataFinal
	 * @return
	 */
	public static String calcularDiferencaTempos(Date dataInicial, Date dataFinal) {

		if (dataInicial != null && dataFinal != null) {
			Calendar dataInicio = Calendar.getInstance();
			dataInicio.setTime(dataInicial);
			dataInicio.set(Calendar.SECOND, 0);
			dataInicio.set(Calendar.MILLISECOND, 0);

			Calendar dataTermino = Calendar.getInstance();
			dataTermino.setTime(dataFinal);
			dataTermino.set(Calendar.SECOND, 0);
			dataTermino.set(Calendar.MILLISECOND, 0);

			long milissegundosDataInicial = dataInicio.getTimeInMillis();
			long milissegundosDataTermino = dataTermino.getTimeInMillis();
			long diferencaMilissegundos = milissegundosDataTermino - milissegundosDataInicial;

			String resultadoExibido = "";
			String textoMinutos = "";
			String textoHoras = "";
			String textoDias = "";

			long days  = TimeUnit.MILLISECONDS.toDays(diferencaMilissegundos);
			long hours = TimeUnit.MILLISECONDS.toHours(diferencaMilissegundos) - TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(diferencaMilissegundos));
			long minutes = TimeUnit.MILLISECONDS.toMinutes(diferencaMilissegundos) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(diferencaMilissegundos));
			//long seconds = TimeUnit.MILLISECONDS.toSeconds(diferencaMilissegundos) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(diferencaMilissegundos));

			textoDias = "d ";
			textoHoras = "h ";
			textoMinutos = "min";


			if (days != 0) {
				// Exibi��o com segundos			      
				//resultadoExibido = String.format(days+"Dias"+hours+"Horas"+minutes+"Minutos"+seconds+"Segundos");
				resultadoExibido = String.format(days+textoDias+hours+textoHoras+minutes+textoMinutos);
			} else if (minutes < 1) {
				resultadoExibido = "1min"; 
			} else if (hours > 0){
				// Exibi��o com segundos 
				//resultadoExibido = String.format(hours+"Horas"+minutes+"Minutos"+seconds+"Segundos");
				resultadoExibido = String.format(hours+textoHoras+minutes+textoMinutos);
			} else {
				resultadoExibido = String.format(minutes+textoMinutos);
			}
			return resultadoExibido;
		}  else {
			return "";
		}
	}
	
	public static boolean verificaSabado(Date data) {
		Calendar dataVerificar = Calendar.getInstance();
        dataVerificar.setTime(data);
        
        int diaDaSemana = dataVerificar.get(Calendar.DAY_OF_WEEK);
        if (diaDaSemana == Calendar.SATURDAY) {
			return true;
		} 
		return false;
	}

	public static boolean verificaDomingo(Date data) {
		Calendar dataVerificar = Calendar.getInstance();
		dataVerificar.setTime(data);
		
		int diaDaSemana = dataVerificar.get(Calendar.DAY_OF_WEEK);
		if (diaDaSemana == Calendar.SUNDAY) {
			return true;
		} 
		return false;
	}
	
	public static Date retornaDataAutalMenosXDias(int quantidade) {
		Calendar data = Calendar.getInstance();
		data.add(Calendar.DAY_OF_MONTH, -10);
		
		return data.getTime(); 
	}
	
	public static Date recuperaDataAutalMaisXDias(int quantidade) {
		Calendar data = Calendar.getInstance();
		data.add(Calendar.DAY_OF_MONTH, +10);
		
		return data.getTime(); 
	}
	
	public static Map<String, Integer> diferencaAnoMes(Date dataInicio, Date dataFim) {
        Map<String, Integer> mapRetorno = new HashMap<>();
		
		Calendar fromDate=Calendar.getInstance();
        Calendar toDate=Calendar.getInstance();
        fromDate.setTime(dataInicio);
        toDate.setTime(dataFim);
        
        int increment = 0;
        int anos,meses;
        int dias;
        
        if (fromDate.get(Calendar.DAY_OF_MONTH) > toDate.get(Calendar.DAY_OF_MONTH)) {
            increment =fromDate.getActualMaximum(Calendar.DAY_OF_MONTH);
        }
        if (increment != 0) {
            dias = (toDate.get(Calendar.DAY_OF_MONTH) + increment) - fromDate.get(Calendar.DAY_OF_MONTH);
            increment = 1;
        } else {
            dias = toDate.get(Calendar.DAY_OF_MONTH) - fromDate.get(Calendar.DAY_OF_MONTH);
        }
        mapRetorno.put("dias", dias);
        
        if ((fromDate.get(Calendar.MONTH) + increment) > toDate.get(Calendar.MONTH)) {
            meses = (toDate.get(Calendar.MONTH) + 12) - (fromDate.get(Calendar.MONTH) + increment);
            increment = 1;
        } else {
            meses = (toDate.get(Calendar.MONTH)) - (fromDate.get(Calendar.MONTH) + increment);
            increment = 0;
        }
        mapRetorno.put("meses", meses);
        
        anos = toDate.get(Calendar.YEAR) - (fromDate.get(Calendar.YEAR) + increment);
        mapRetorno.put("anos", anos);
        
        return mapRetorno;
	}
	
	public static Date prepararDataInicioAno(Integer ano) {
		
		Calendar data = Calendar.getInstance();
		Date date = prepararDataInicioDia(data.getTime());
		data.setTime(date);
		data.set(Calendar.DAY_OF_MONTH, 01);
		data.set(Calendar.MONTH, Calendar.JANUARY);
		data.set(Calendar.YEAR, ano);
		
		return data.getTime();
		
	}
	
	public static Date prepararDataFimAno(Integer ano) {
		
		Calendar data = Calendar.getInstance();
		Date date = prepararDataFimDia(data.getTime());
		data.setTime(date);
		data.set(Calendar.DAY_OF_MONTH, 31);
		data.set(Calendar.MONTH, Calendar.DECEMBER);
		data.set(Calendar.YEAR, ano);
		
		return data.getTime();
		
	}
	
}
